package World.Module.ObjectPool;

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

public class Pool {

    private final Class<?> ObjectType;
    private final int MaxCapacity;

    private final ConcurrentLinkedQueue<Object> _items = new ConcurrentLinkedQueue<>();

    private final AtomicReference<Object> FastItem = new AtomicReference<>(null);
    private final AtomicInteger NumItems = new AtomicInteger(0);

    public Pool(Class<?> objectType, int maxCapacity)
    {
        this.ObjectType = objectType;
        this.MaxCapacity = maxCapacity;
    }

    public Object Get()
    {
        //通过FastItem节约从_items取的时间
        Object item = FastItem.get();
        if(item == null || FastItem.compareAndExchange(item, null) != item)
        {
            if(_items.isEmpty())
            {
                try {
                    return this.ObjectType.getConstructor().newInstance();
                } catch (NoSuchMethodException | InvocationTargetException | InstantiationException |
                         IllegalAccessException e) {
                    throw new RuntimeException("Class no parameterless constructor!");
                }
            }
            NumItems.decrementAndGet();
            return _items.poll();
        }
        return item;
    }

    public void Return(Object object) {
        if (FastItem.get() != null || FastItem.compareAndExchange(null, object) != null) {
            if(NumItems.incrementAndGet() <= MaxCapacity)
            {
                _items.offer(object);
                return;
            }
            NumItems.decrementAndGet();
        }
    }
}
